/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.springblade.modules.admin.service.impl;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.*;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.sida.voice.service.VoiceTemplate;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.impl.util.TimerUtil;
import org.springblade.common.cache.DictCache;
import org.springblade.common.constant.BaseRoleConstant;
import org.springblade.common.constant.MaintenanceSmsConstant;
import org.springblade.common.constant.TemplateMsgConstant;
import org.springblade.common.constant.VoiceConstant;
import org.springblade.common.mq.MqMessageService;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.base.BaseEntity;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.redis.cache.BladeRedis;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.constant.BladeConstant;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.modules.admin.dto.PlanContentSaveDto;
import org.springblade.modules.admin.dto.PlanLogDTO;
import org.springblade.modules.admin.dto.mal.MalListDTO;
import org.springblade.modules.admin.dto.sugar.SugarSearchDTO;
import org.springblade.modules.admin.dto.sugar.mal.SugarMalSearchDTO;
import org.springblade.modules.admin.entity.*;
import org.springblade.modules.admin.enums.*;
import org.springblade.modules.admin.mapper.MaintainMalfunctionWorkMapper;
import org.springblade.modules.admin.mapper.SparepartPricesMapper;
import org.springblade.modules.admin.service.*;
import org.springblade.modules.admin.utils.AsyncUtils;
import org.springblade.modules.admin.utils.DateUtils;
import org.springblade.modules.admin.utils.MapUtil;
import org.springblade.modules.admin.vo.*;
import org.springblade.modules.admin.vo.elevator.ProblemItemVo;
import org.springblade.modules.admin.vo.parts.MaintainMalfunctionWorkDetailVo;
import org.springblade.modules.admin.vo.parts.MalfunctionPartsTreeVO;
import org.springblade.modules.admin.vo.plan.MalfunctionWorkSummaryVo;
import org.springblade.modules.admin.vo.plan.PlanMaintainUserVO;
import org.springblade.modules.admin.vo.plan.PlanTemplateDescVO;
import org.springblade.modules.admin.vo.plan.PlanUserSignDetailVo;
import org.springblade.modules.admin.vo.plan.wx.*;
import org.springblade.modules.admin.vo.plan.wx.bi.BiWxUserPlanVo;
import org.springblade.modules.admin.vo.sugar.StatisticsTrendVO;
import org.springblade.modules.admin.vo.sugar.mal.ElevatorMalTopVO;
import org.springblade.modules.admin.vo.sugar.map.BuildingMapVo;
import org.springblade.modules.admin.wrapper.MaintainPlanContentWrapper;
import org.springblade.modules.notice.annotation.MsgNotice;
import org.springblade.modules.notice.enums.BusinessType;
import org.springblade.modules.notice.enums.TriggerNodeEnum;
import org.springblade.modules.resource.utils.SmsUtil;
import org.springblade.modules.system.entity.Dict;
import org.springblade.modules.system.entity.TenantConfig;
import org.springblade.modules.system.entity.User;
import org.springblade.modules.system.service.*;
import org.springblade.modules.system.vo.SimpleUserVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 故障工单明细 服务实现类
 *
 * @author BladeX
 * @since 2021-05-11
 */
@Service
@Slf4j
public class MaintainMalfunctionWorkServiceImpl extends BaseServiceImpl<MaintainMalfunctionWorkMapper, MaintainMalfunctionWork> implements IMaintainMalfunctionWorkService {

	@Resource
	@Lazy
	private IMaintainPlanContentService maintainPlanContentService;
	@Autowired
	private IMaintainSignService signService;
	@Autowired
	private IMaintainPlanContentUserService maintainPlanContentUserService;
	@Autowired
	private IMaintainMalfunctionHistoryService malfunctionHistoryService;
	@Autowired
	private IUserService userService;

	@Autowired
	private SparepartPricesMapper sparepartPricesMapper;

	@Autowired
	private IDictService dictService;

	@Autowired
	private WeChatDialogueService weChatDialogueService;

	@Autowired
	private IBusinessApproveService businessApproveService;

	@Autowired
	private AsyncUtils asyncUtils;

	@Autowired
	private MaintainMalfunctionLogService malfunctionLogService;

	@Autowired
	private IElevatorDetailService elevatorDetailService;

	@Autowired
	private ElevatorService elevatorService;

	@Autowired
	private BuildingService buildingService;

	@Autowired
	private IBuildingExtService buildingExtService;

	@Autowired
	private IMaintainPlanContentExtService maintainPlanContentExtService;

	@Autowired
	private MqMessageService mqMessageService;

	@Autowired
	private IUserTrajectoryService userTrajectoryService;

	@Autowired
	private IMaintainWxmsgTypeService maintainWxmsgTypeService;

	@Autowired
	private BladeRedis bladeRedis;
	@Autowired
	private UserExtService userExtService;

	@Autowired
	private TenantConfigService tenantConfigService;

	@Autowired
	private IRoleService roleService;

	@Autowired
	private IWxFaultCauseService wxFaultCauseService;
	@Autowired
	private IDeptService deptService;
	@Autowired
	private ElevatorPrincipalDeptService elevatorPrincipalDeptService;

	@Override
	public IPage<MaintainMalfunctionWorkVO> selectMaintainMalfunctionWorkPage(IPage<MaintainMalfunctionWorkVO> page, MaintainMalfunctionWorkVO maintainMalfunctionWork) {
		return page.setRecords(baseMapper.selectMaintainMalfunctionWorkPage(page, maintainMalfunctionWork));
	}

	@Override
	public MalFunctionDetailVO getMalfunctionWorkDetail(Long planId) {
		List<MalFunctionDetailVO> list = this.getMalfunctionWorkDetailList(Collections.singletonList(planId));
		return list.size() > 0 ? list.get(0) : null;
	}

	@Override
	public List<MalFunctionDetailVO> getMalfunctionWorkDetailList(List<Long> planIds) {
		List<MaintainPlanContent> maintainPlanContentList = maintainPlanContentService.list(Wrappers.<MaintainPlanContent>lambdaQuery().in(MaintainPlanContent::getId, planIds));
		Map<Long, MaintainPlanContent> listMap = maintainPlanContentList.stream().collect(Collectors.toMap(MaintainPlanContent::getId, Function.identity()));

		// 查询用户信息
		List<User> userList = userService.list();
		Map<Long, User> userMap = userList.stream().collect(Collectors.toMap(User::getId, Function.identity()));

		// 查询模板信息
		List<PlanTemplateDescVO> descList = maintainPlanContentService.getPlanTemplateNames(planIds);
		Map<Long, PlanTemplateDescVO> descMap = descList.stream().collect(Collectors.toMap(PlanTemplateDescVO::getPlanId, Function.identity(), (t1, t2) -> t1));

		// 查询维修操作记录
		List<MalFunctionHistoryVO> malFunctionHistorieList = malfunctionHistoryService.selectByPlanIds(planIds);
		Map<Long, List<MalFunctionHistoryVO>> malFunctionHistoryMap = malFunctionHistorieList.stream().collect(Collectors.groupingBy(MalFunctionHistoryVO::getPlanId));

		// 查询关联人员信息
		List<MaintainPlanContentUser> planContentUserList = maintainPlanContentUserService.list(Wrappers.<MaintainPlanContentUser>lambdaQuery().in(MaintainPlanContentUser::getPlanId, planIds));
		Map<Long, List<MaintainPlanContentUser>> planContentUserMap = planContentUserList.stream().collect(Collectors.groupingBy(MaintainPlanContentUser::getPlanId));

		// 查询签到信息
		List<MaintainSign> signList = signService.list(Wrappers.<MaintainSign>lambdaQuery().in(MaintainSign::getPlanId, planIds));
		Map<Long, List<MaintainSign>> signMap = signList.stream().collect(Collectors.groupingBy(MaintainSign::getPlanId));

		//2023-04-06 新增审批信息返回
		List<BusinessApprove> businessApproveList = businessApproveService.list(Wrappers.<BusinessApprove>lambdaQuery().in(BusinessApprove::getWorkOrderId, planIds));
		Map<Long, BusinessApprove> businessApproveMap = businessApproveList.stream().collect(Collectors.toMap(BusinessApprove::getWorkOrderId, Function.identity(), (t1, t2) -> t1));

		// 查询电梯详情
		List<Long> elevatorIds = maintainPlanContentList.stream().map(t -> t.getElevatorId()).collect(Collectors.toList());
		List<ElevatorDetail> elevatorDetailList = elevatorDetailService.list(Wrappers.<ElevatorDetail>lambdaQuery().in(ElevatorDetail::getElevatorId, elevatorIds));
		Map<Long, ElevatorDetail> elevatorDetailMap = elevatorDetailList.stream().collect(Collectors.toMap(ElevatorDetail::getElevatorId, Function.identity(), (t1, t2) -> t1));

		// 查询电梯信息
		List<Elevator> elevatorList = elevatorService.listByIds(elevatorIds);
		Map<Long, Elevator> elevatorMap = elevatorList.stream().collect(Collectors.toMap(Elevator::getId, Function.identity()));

		// 查询该任务电梯最近一次完成的任务
		List<LastPlanVO> lastPlanList = maintainPlanContentService.selectElevatorLastPlans(elevatorIds, planIds);
		Map<Long, LastPlanVO> lastPlanMap = lastPlanList.stream().collect(Collectors.toMap(LastPlanVO::getElevatorId, Function.identity()));

		// 查询维修详情

		List<MalFunctionDetailVO> malFunctionDetailList = baseMapper.selectMalfunctionDetailList(planIds);
		Map<Long, List<WxFaultCause>> wxFaultCauseMap = wxFaultCauseService.list().stream().collect(Collectors.groupingBy(WxFaultCause::getId));
		for (MalFunctionDetailVO malFunctionDetailVO : malFunctionDetailList) {
			Long planId = malFunctionDetailVO.getPlanId();
			MaintainPlanContent planContent = listMap.get(planId);
			if (Func.isNotEmpty(malFunctionDetailVO.getFaultMessageList())) {
				malFunctionDetailVO.getFaultMessageList().forEach(e -> {
					// 封装故障现象信息
					if (StringUtil.isNotBlank(e.getProblemItem())) {
						List<String> problemKeys = Func.toStrList(e.getProblemItem());
						List<String> problemNames = new ArrayList<>();
						for (String problemKey : problemKeys) {
							String problemName = DictCache.getValue("fault_problem", problemKey);
							problemNames.add(problemName);
						}
						e.setProblemItemNames(problemNames);
					}
					if (StringUtil.isNotBlank(e.getFaultReasonItem())) {
						List<String> problemKeys = Func.toStrList(e.getFaultReasonItem());
						List<String> problemNames = new ArrayList<>();
						for (String problemKey : problemKeys) {
							List<WxFaultCause> wxFaultCauses = wxFaultCauseMap.get(Convert.toLong(problemKey));
							if (wxFaultCauses != null && wxFaultCauses.size() > 0) {
								problemNames.add(wxFaultCauses.get(0).getFaultName());
							}
						}
						e.setFaultReasonNames(problemNames);
					}
					// 2024-04-26 封装user_name
					if (!Func.isNull(e.getCreateUserId())) {
						User createUser = userMap.get(e.getCreateUserId());
						e.setCreateUserName(createUser.getRealName());
					}
				});
			}
			// 查询该任务电梯最近一次完成的任务
			LastPlanVO lastPlanVO = lastPlanMap.get(malFunctionDetailVO.getElevatorId());
			if (ObjectUtil.isNotEmpty(lastPlanVO)) {
				String desc = "";
				if (lastPlanVO.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_BY.getId())) {
					desc = descMap.get(planId) == null ? "" : descMap.get(planId).getDescription();
				} else if (lastPlanVO.getTypeStatus().equals(MaintainPlanContentEnum.MAINTAIN_WX.getId())) {
					desc = "故障维修";
				}
				lastPlanVO.setDesc(desc);
				lastPlanVO.setStatusName(TaskStatusEnum.getTaskName(lastPlanVO.getTypeStatus(), lastPlanVO.getStatus()));
			}

			// 查询维修操作记录
			List<MalFunctionHistoryVO> malFunctionHistories = malFunctionHistoryMap.get(planId);
			malFunctionDetailVO.setMalFunctionHistories(malFunctionHistories);

			// 查询关联人员信息
			List<MaintainPlanContentUser> planContentUsers = planContentUserMap.get(planId);
			if (Func.isNotEmpty(planContentUsers)) {
				planContentUsers = planContentUsers.stream().filter(e -> {
					User user = userMap.get(e.getUserId());
					if (Func.isEmpty(user)) {
						return false;
					}
					String userName = user.getRealName();
					e.setUserName(userName);
					List<MaintainSign> userSigns = signMap.get(e.getPlanId());
					if (Func.isNotEmpty(userSigns)) {
						long userSignCount = signMap.get(e.getPlanId()).stream().filter(t -> t.getUserId() == e.getUserId()).count();
						e.setUserSignCount((int) userSignCount);
						if (planContent.getStatus().equals(TaskStatusEnum.WX_SIGN_FINISH.getStatus())) {
							if (userSignCount > 0) {
								return true;
							}
						} else {
							return true;
						}
					}
					return false;
				}).collect(Collectors.toList());
			}
			malFunctionDetailVO.setPlanContentUsers(planContentUsers);

			//2023-04-06 新增审批信息返回
			BusinessApprove businessApprove = businessApproveMap.get(planId);
			// 2024-05-06 新增判断
			if (!Func.isNull(businessApprove)) {
				Long remarkUpdateUser = businessApprove.getRemarkUpdateUser();
				if (!Func.isNull(remarkUpdateUser)) {
					User user = userMap.get(remarkUpdateUser);
					if (!Func.isNull(user)) {
						String realName = user.getRealName();
						businessApprove.setApproveName(realName);
					} else {
						businessApprove.setApproveName(null);
					}
				} else {
					businessApprove.setApproveName(null);
				}
			}
			malFunctionDetailVO.setBusinessApprove(businessApprove);

			if (planContent.getFinishDate() == null) {
				malFunctionDetailVO.setPlanFinishDate(null);
			} else {
				malFunctionDetailVO.setPlanFinishDate(planContent.getFinishDate().getTime());
			}

			// 2023-09-13 新增电梯唯一识别码、building id
			Long elevatorId = planContent.getElevatorId();
			ElevatorDetail elevatorDetail = elevatorDetailMap.get(elevatorId);
			String elevatorNum = elevatorDetail.getElevatorNum();
			malFunctionDetailVO.setElevatorNum(elevatorNum);
			Elevator elevator = elevatorMap.get(elevatorId);
			Long buildingId = elevator.getBuildingId();
			malFunctionDetailVO.setBuildingId(buildingId);
			// 2024-06-03 新增新来源类型返回-此处返回的是此工单的类型
			Integer typeStatus = planContent.getTypeStatus();
			malFunctionDetailVO.setPlanTypeName(MaintainPlanContentEnum.getName(typeStatus));
		}

		return malFunctionDetailList;
	}

	@Override
	public MaintainMalfunctionWorkDetailVo getDetail(Long planId) {
		return baseMapper.getDetail(planId);
	}


	public MalFunctionDetailVO selectMalfunctionDetail(Long planId) {
		return baseMapper.selectMalfunctionDetail(planId);
	}


	@Override
	public MalfunctionWorkSummaryVo getSummaryDetail() {

		MalfunctionWorkSummaryVo malfunctionWorkSummaryVo = new MalfunctionWorkSummaryVo();
		final List<Integer> statusList = sparepartPricesMapper.getPlanPartSummary(MaintainPlanContentEnum.MAINTAIN_WX.getId());
		malfunctionWorkSummaryVo.setPlanCounts(statusList.size());

		final List<Integer> disPlanCounts = statusList.stream().filter(o -> o == TaskStatusEnum.WX_PENDING.getStatus()).collect(Collectors.toList());
		malfunctionWorkSummaryVo.setDisPlanCounts(disPlanCounts.size());

		List<Integer> disPlanUserCounts = statusList.stream().filter(o -> o == TaskStatusEnum.WX_ALLOCATION.getStatus()).collect(Collectors.toList());
		malfunctionWorkSummaryVo.setDisPlanUserCounts(disPlanUserCounts.size());


		final List<Integer> acceptPlanCounts = statusList.stream().filter(o -> o == TaskStatusEnum.WX_TO_START.getStatus() || o == TaskStatusEnum.WX_UNDER_WAY.getStatus() || o == TaskStatusEnum.WX_SIGN_FINISH.getStatus()).collect(Collectors.toList());
		malfunctionWorkSummaryVo.setAcceptPlanCounts(acceptPlanCounts.size());

		final List<Integer> disAceptPlanCounts = statusList.stream().filter(o -> o == TaskStatusEnum.WX_TURN_DOWN.getStatus()).collect(Collectors.toList());
		malfunctionWorkSummaryVo.setDisAceptPlanCounts(disAceptPlanCounts.size());

		final List<Integer> revocationCounts = statusList.stream().filter(o -> o == TaskStatusEnum.WX_CLOSED.getStatus()).collect(Collectors.toList());
		malfunctionWorkSummaryVo.setRevocationCounts(revocationCounts.size());

		final List<Integer> disSignCounts = statusList.stream().filter(o -> o == TaskStatusEnum.WX_TO_START.getStatus()).collect(Collectors.toList());
		malfunctionWorkSummaryVo.setDisSignCounts(disSignCounts.size());

		final List<Integer> enSignCounts = statusList.stream().filter(o -> o == TaskStatusEnum.WX_UNDER_WAY.getStatus()).collect(Collectors.toList());
		malfunctionWorkSummaryVo.setEnSignCounts(enSignCounts.size());

		final List<Integer> finishCounts = statusList.stream().filter(o -> o == TaskStatusEnum.WX_SIGN_FINISH.getStatus()).collect(Collectors.toList());
		malfunctionWorkSummaryVo.setFinishCounts(finishCounts.size());
		return malfunctionWorkSummaryVo;
	}

	@Override
	public List<ProblemItemVo> getElevatorFaultList(Long elevatorId) {

		List<ProblemItemVo> problemItemVos = new ArrayList<>(16);
		List<Dict> problem = dictService.getList("fault_problem");
		List<MaintainMalfunctionWork> list = baseMapper.getElevatorFaultList(elevatorId);
		List<String> strings = list.stream().map(MaintainMalfunctionWork::getProblemItem).collect(Collectors.toList());
		List<String> problemItemList = new ArrayList<>(16);
		for (String str : strings) {
			if (StrUtil.isNotEmpty(str)) {
				List<String> list1 = Arrays.asList(str.split(","));
				problemItemList.addAll(list1);
			}
		}
		for (Dict dict : problem) {
			ProblemItemVo problemItemVo = new ProblemItemVo();
			problemItemVo.setDictKey(dict.getDictKey());
			problemItemVo.setDictValue(dict.getDictValue());
			Integer counts = problemItemVo.getCounts();
			for (String str : problemItemList) {
				if (dict.getDictKey().equals(str)) {
					counts = counts + 1;
				}
			}
			problemItemVo.setCounts(counts);
			problemItemVos.add(problemItemVo);
		}
		return problemItemVos;
	}

	@Override
	public MalfunctionWorkSummaryVo getMalfunctionWorkElevatorInfo(Long elevatorId) {
		MalfunctionWorkSummaryVo malfunctionWorkSummaryVo = new MalfunctionWorkSummaryVo();
		List<MaintainPlanContent> list = baseMapper.getMalfunctionWorkElevatorInfo(elevatorId);
		int wxToStartSize = Convert.toInt(list.stream().filter(o -> o.getStatus() == TaskStatusEnum.WX_TO_START.getStatus()).collect(Collectors.toList()).size());
		List<Long> ids = list.stream().filter(o -> o.getStatus() == TaskStatusEnum.WX_UNDER_WAY.getStatus()).map(MaintainPlanContent::getId).collect(Collectors.toList());
		int wxUnderWaySize = Convert.toInt(ids.size());
		int wxSignFinishSize = Convert.toInt(list.stream().filter(o -> o.getStatus() == TaskStatusEnum.WX_SIGN_FINISH.getStatus()).collect(Collectors.toList()).size());

		//进行中
		malfunctionWorkSummaryVo.setEnSignCounts(wxUnderWaySize);
		malfunctionWorkSummaryVo.setEnSignIds(ids);
		//已完成
		malfunctionWorkSummaryVo.setFinishCounts(wxSignFinishSize);
		//待开始
		malfunctionWorkSummaryVo.setDisSignCounts(wxToStartSize);
		return malfunctionWorkSummaryVo;
	}

	@MsgNotice(businessType = BusinessType.REPAIR, node = TriggerNodeEnum.ASSIGN, parameterName = "planId")
	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean addMalfunctionWorkUser(Long planId, String userIds) {

		List<Long> asList = new ArrayList<>();
		String[] split = userIds.split(",");
		for (int i = 0; i < split.length; i++) {
			asList.add(Convert.toLong(split[i]));
		}
		List<MaintainPlanContentUser> userList = maintainPlanContentUserService.list(Wrappers.<MaintainPlanContentUser>lambdaQuery().eq(MaintainPlanContentUser::getPlanId, planId));
		List<Long> longs = userList.stream().map(MaintainPlanContentUser::getUserId).collect(Collectors.toList());
		List<String> list = Arrays.asList(userIds.split(","));
		List<String> list1 = new ArrayList<>(16);
		list1.addAll(list);
		List<String> list2 = new ArrayList<>(16);
		for (Long userId : longs) {
			list2.add(Convert.toStr(userId));
		}
		list1.removeAll(list2);
		List<String> userName = userService.listByIds(list1).stream().map(User::getRealName).collect(Collectors.toList());
		MaintainPlanContent maintainPlanContent = maintainPlanContentService.getById(planId);
		if (userList.size() == 0) {
			malfunctionLogService.insertWorkLog(maintainPlanContent.getId(), WorkTrackStatusEnum.ADD_USER.getTypeName() + "[" + StrUtil.join("/", userName) + "]", TaskStatusEnum.WX_TO_START.getStatus());
		} else {
			malfunctionLogService.insertWorkLog(maintainPlanContent.getId(), "增派人员" + "[" + StrUtil.join("/", userName) + "]", TaskStatusEnum.WX_TO_START.getStatus());
		}

		List<Long> planUserIds = userList.stream().map(MaintainPlanContentUser::getUserId).collect(Collectors.toList());
		asList.removeAll(planUserIds);
		if (asList.size() == 0) {
			return true;
		}

		//计算维修达到时间
		PlanContentSaveDto planContentSaveDto = new PlanContentSaveDto();
		Long buildingId = elevatorService.getById(maintainPlanContent.getElevatorId()).getBuildingId();
		planContentSaveDto.setBuildingId(buildingId);
		BuildingExt buildingExt = buildingExtService.getOne(Wrappers.<BuildingExt>lambdaQuery().eq(BuildingExt::getBuildingId, planContentSaveDto.getBuildingId()));
		if (StrUtil.isNotEmpty(buildingExt.getMalfunctionWorkArrivalTime())) {
			//预计达到时间
			long timeMillis = System.currentTimeMillis();
			if (buildingExt.getMalfunctionWorkArrivalTime().contains("m")) {
				Long time = Convert.toLong(buildingExt.getMalfunctionWorkArrivalTime().replace("m", "")) * 60 * 1000;
				timeMillis = timeMillis + time;
				Date date2 = new Date(timeMillis);
				planContentSaveDto.setPlanArriveDate(date2);
			} else if (buildingExt.getMalfunctionWorkArrivalTime().contains("h")) {
				Long time = Convert.toLong(buildingExt.getMalfunctionWorkArrivalTime().replace("h", "")) * 60 * 60 * 1000;
				timeMillis = timeMillis + time;
				Date date2 = new Date(timeMillis);
				planContentSaveDto.setPlanArriveDate(date2);
			}
		}

//		MaintainMalfunctionWork maintainMalfunctionWork = this.getOne(Wrappers.<MaintainMalfunctionWork>lambdaQuery().eq(MaintainMalfunctionWork::getPlanId, planId).orderByAsc(MaintainMalfunctionWork::getId), false);
//		ElevatorSimpleInfoVO elevatorInfo = maintainPlanContentService.getElevatorSimpleInfo(planId);
		for (Long userId : asList) {
			//添加人员信息
			MaintainPlanContentUser maintainPlanContentUser = new MaintainPlanContentUser();
			maintainPlanContentUser.setUserId(Convert.toLong(userId));
			maintainPlanContentUser.setPlanId(planId);
			if (planContentSaveDto.getPlanArriveDate() != null) {
				maintainPlanContentUser.setPlanArriveDate(new Date(DateUtils.getNowDateEnd(planContentSaveDto.getPlanArriveDate())));
			}
			SimpleUserVO assignUserInfo = userService.getSimpleUserInfo(Convert.toLong(userId));
			String phone1 = assignUserInfo.getPhone();

			PlanUserSignDetailVo planUserSignDetailVo = new PlanUserSignDetailVo();
			planUserSignDetailVo.setUserName(userService.getById(Convert.toLong(userId)).getRealName());
			maintainPlanContentUser.setSignInfo(JSON.toJSONString(planUserSignDetailVo));

			maintainPlanContentUserService.save(maintainPlanContentUser);
//			if (Func.isNotEmpty(assignUserInfo)) {
//				if (Func.isNotEmpty(assignUserInfo.getOpenid())) {
//					log.info("===========给维修发送模板消息,维修人:[{}]===========", assignUserInfo.getUserName());
//					// 跳转链接
//					String skipUrl = String.format("subpages/repair/repariDetail?elevatorId=%s&planId=%s", elevatorInfo.getElevatorId(), planId);
//					Map<String, String> templateDataMap = new HashMap<>(8);
//					templateDataMap.put("first", "您好，您有新的维修任务!");
//					templateDataMap.put("keyword1", maintainMalfunctionWork == null ? null : maintainMalfunctionWork.getName());
//					templateDataMap.put("keyword2", maintainMalfunctionWork == null ? null : maintainMalfunctionWork.getPhone());
//					templateDataMap.put("keyword3", DateUtil.format(new Date(), DatePattern.NORM_DATETIME_MINUTE_PATTERN));
//					templateDataMap.put("keyword4", maintainMalfunctionWork == null ? null : maintainMalfunctionWork.getMfDesc());
//					templateDataMap.put("remark", "请及时登录梯无忧小程序执行维修任务!");
//					templateDataMap.put("params", skipUrl);
//					weChatDialogueService.sendMsg(assignUserInfo.getOpenid(), TemplateMsgConstant.T_REPAIR_TASK_ID, templateDataMap);
//				}
//				log.info("===========给维修人发送手机短信,维修人:[{}], 手机号码:[{}]===========", assignUserInfo.getUserName(), phone1);
//				Map<String, String> smsParam = new HashMap<>(2);
//				smsParam.put("auditStatus", getPlanStatusName(maintainPlanContent));
//				SmsUtil.sendMessage(MaintenanceSmsConstant.MAINTENANCE_PEOPLE, BladeConstant.ADMIN_TENANT_ID, smsParam, phone1);
//
//				log.info("===========给维修人打电话,审批人:[{}], 手机号码:[{}]===========", assignUserInfo.getUserName(), assignUserInfo.getPhone());
//				Map<String, String> phoneMap = new HashMap<>(2);
//				phoneMap.put("place", elevatorInfo.getBuildingName() + elevatorInfo.getElevatorAddress());
//				VoiceTemplate voiceTemplate = new VoiceTemplate();
//				voiceTemplate.setTemplateCode(VoiceConstant.MAINTENANCE_ADD_USER);
//				voiceTemplate.setTemplateParam(phoneMap);
//				voiceTemplate.setPhoneNumber(phone1);
//				asyncUtils.sendPhone(voiceTemplate);
//			}
		}

		// 更新分配时间与分配次数
		MaintainPlanContentExt maintainPlanContentExt = maintainPlanContentExtService.getOne(Wrappers.<MaintainPlanContentExt>lambdaQuery().eq(MaintainPlanContentExt::getPlanId, planId), false);
		if (Func.isEmpty(maintainPlanContentExt)) {
			throw new ServiceException("数据异常！");
		}
		if (maintainPlanContentExt.getAssignmentCounts() == 0) {
			Date now = new Date();
			maintainPlanContentExt.setAllocateTime(now);
			long allocateDuration = now.getTime() - maintainPlanContent.getCreateTime().getTime();
			maintainPlanContentExt.setAllocateDuration(allocateDuration < 0 ? 0 : allocateDuration);
		}
		maintainPlanContentExt.setAssignmentCounts(maintainPlanContentExt.getAssignmentCounts() + 1);
		maintainPlanContentExt.setAddUserFlag(1);
		boolean tsFlag = roleService.hasRole(asList, BaseRoleConstant.TECHNICAL_SUPPORT);
		if (tsFlag) {
			maintainPlanContentExt.setApplyTsFlag(1);
		}
		boolean peFlag = roleService.hasRole(asList, BaseRoleConstant.EXPERT);
		if (peFlag) {
			maintainPlanContentExt.setApplyPeFlag(1);
		}
		maintainPlanContentExtService.updateById(maintainPlanContentExt);
		List<PlanMaintainUserVO> maintainUserList = new ArrayList<>();
		for (Long userId : asList) {
			PlanMaintainUserVO planMaintainUserVO = new PlanMaintainUserVO();
			planMaintainUserVO.setMaintainUserId(userId);
			maintainUserList.add(planMaintainUserVO);
		}
		planContentSaveDto.setMaintainUserList(maintainUserList);
		planContentSaveDto.setPlanDate(DateUtil.format(new Date(), "yyyy-MM-dd"));
		this.sendYjMsg(planContentSaveDto, planId);
		return true;
	}


	@MsgNotice(businessType = BusinessType.REPAIR, node = TriggerNodeEnum.ASSIGN, parameterName = "planId")
	@Override
	public Boolean giveOtherUser(Long planId, String userIds) {
		MaintainPlanContent maintainPlanContent = maintainPlanContentService.getById(planId);

		//计算维修达到时间
		PlanContentSaveDto planContentSaveDto = new PlanContentSaveDto();
		Long buildingId = elevatorService.getById(maintainPlanContent.getElevatorId()).getBuildingId();
		planContentSaveDto.setBuildingId(buildingId);
		BuildingExt buildingExt = buildingExtService.getOne(Wrappers.<BuildingExt>lambdaQuery().eq(BuildingExt::getBuildingId, planContentSaveDto.getBuildingId()));
		if (StrUtil.isNotEmpty(buildingExt.getMalfunctionWorkArrivalTime())) {
			//预计达到时间
			long timeMillis = System.currentTimeMillis();
			if (buildingExt.getMalfunctionWorkArrivalTime().contains("m")) {
				Long time = Convert.toLong(buildingExt.getMalfunctionWorkArrivalTime().replace("m", "")) * 60 * 1000;
				timeMillis = timeMillis + time;
				Date date2 = new Date(timeMillis);
				planContentSaveDto.setPlanArriveDate(date2);
			} else if (buildingExt.getMalfunctionWorkArrivalTime().contains("h")) {
				Long time = Convert.toLong(buildingExt.getMalfunctionWorkArrivalTime().replace("h", "")) * 60 * 60 * 1000;
				timeMillis = timeMillis + time;
				Date date2 = new Date(timeMillis);
				planContentSaveDto.setPlanArriveDate(date2);
			}
		}


		List<Long> asList = new ArrayList<>();
		String[] split = userIds.split(",");
		for (int i = 0; i < split.length; i++) {
			asList.add(Convert.toLong(split[i]));
		}
		List<MaintainPlanContentUser> userList = maintainPlanContentUserService.list(Wrappers.<MaintainPlanContentUser>lambdaQuery().eq(MaintainPlanContentUser::getPlanId, planId));
		List<String> userName = userService.listByIds(Arrays.asList(userIds.split(","))).stream().map(User::getRealName).collect(Collectors.toList());
		malfunctionLogService.insertWorkLog(maintainPlanContent.getId(), "转派任务" + "[" + StrUtil.join("/", userName) + "]", TaskStatusEnum.WX_TO_START.getStatus());

		MaintainPlanContentExt maintainPlanContentExt = maintainPlanContentExtService.getOne(Wrappers.<MaintainPlanContentExt>lambdaQuery().eq(MaintainPlanContentExt::getPlanId, planId), false);
		if (Func.isNotEmpty(maintainPlanContentExt)) {
			maintainPlanContentExt.setTransferUserFlag(1);
			boolean tsFlag = roleService.hasRole(asList, BaseRoleConstant.TECHNICAL_SUPPORT);
			if (tsFlag) {
				maintainPlanContentExt.setApplyTsFlag(1);
			}
			boolean peFlag = roleService.hasRole(asList, BaseRoleConstant.EXPERT);
			if (peFlag) {
				maintainPlanContentExt.setApplyPeFlag(1);
			}

			maintainPlanContentExtService.updateById(maintainPlanContentExt);
		}

		//标记工单为转派工单
		List<MaintainMalfunctionWork> malfunctionWorks = this.list(Wrappers.<MaintainMalfunctionWork>lambdaQuery().eq(MaintainMalfunctionWork::getPlanId, planId));
		Integer giveStatus = 1;//表示转派
		malfunctionWorks.forEach(o -> o.setGiveStatus(giveStatus));
		this.updateBatchById(malfunctionWorks);

		if (maintainPlanContent.getStatus().equals(TaskStatusEnum.WX_TO_START.getStatus()) || maintainPlanContent.getStatus().equals(TaskStatusEnum.WX_UNDER_WAY.getStatus())) {
			//第一步判断工单状态
			Integer createFrom = 1;//表示转派
			if (maintainPlanContent.getStatus().equals(TaskStatusEnum.WX_TO_START.getStatus())) {
				maintainPlanContentUserService.removeByIds(userList.stream().map(MaintainPlanContentUser::getId).collect(Collectors.toList()));
				//如果是待开始状态,相当于分配人员
				for (Long userId : asList) {
					//添加人员信息
					MaintainPlanContentUser maintainPlanContentUser = new MaintainPlanContentUser();
					maintainPlanContentUser.setUserId(Convert.toLong(userId));
					maintainPlanContentUser.setPlanId(planId);
					if (planContentSaveDto.getPlanArriveDate() != null) {
						maintainPlanContentUser.setPlanArriveDate(new Date(DateUtils.getNowDateEnd(planContentSaveDto.getPlanArriveDate())));
					}
					maintainPlanContentUser.setCreateFrom(createFrom);
					maintainPlanContentUserService.save(maintainPlanContentUser);
				}
			} else if (maintainPlanContent.getStatus().equals(TaskStatusEnum.WX_UNDER_WAY.getStatus())) {
				//第一步将原有的计划执行人自动签退
				List<MaintainSign> signs2 = signService.list(Wrappers.<MaintainSign>lambdaQuery().eq(MaintainSign::getPlanId, planId));
				List<MaintainSign> signs = signs2.stream().filter(o -> o.getSignOutTime() == null).collect(Collectors.toList());
				if (signs.size() > 0) {
					Integer status = 2;//系统代签
					signs.forEach(o -> {
						o.setStatus(status);
						o.setSignOutStatus(SignStatusEnum.NORMAL.getId());
						o.setSignOutTime(new Date());
					});
					signService.updateBatchById(signs);
					//第二步插入log日志
					List<Long> signUserIds = signs.stream().map(MaintainSign::getUserId).collect(Collectors.toList());
					List<String> userNames = userService.listByIds(signUserIds).stream().map(User::getRealName).collect(Collectors.toList());
					PlanLogDTO planLogDTO = new PlanLogDTO();
					planLogDTO.setExpDesc("系统代签");
					malfunctionLogService.insertWorkLog(maintainPlanContent.getId(), "签退", maintainPlanContent.getStatus(), JSON.toJSONString(planLogDTO), AuthUtil.getUserId(), String.join("/", userNames));
					//将已签到的用户头像头像设置为不亮
					List<MaintainPlanContentUser> closeUserHears = userList.stream().filter(o -> signUserIds.contains(o.getUserId())).collect(Collectors.toList());
					for (MaintainPlanContentUser maintainPlanContentUser : closeUserHears) {
						PlanUserSignDetailVo signUser = maintainPlanContentUser.getSignUser();
						signUser.setIsPlanStatus(false);
						maintainPlanContentUser.setSignInfo(JSON.toJSONString(signUser));
					}
					maintainPlanContentUserService.updateBatchById(closeUserHears);

				}
				//第三步将未签到的用户剔除
				maintainPlanContentUserService.remove(Wrappers.<MaintainPlanContentUser>lambdaQuery().eq(MaintainPlanContentUser::getPlanId, planId).notIn(MaintainPlanContentUser::getUserId, signs2.stream().map(MaintainSign::getUserId).collect(Collectors.toList())));
				List<MaintainPlanContentUser> planUserList = maintainPlanContentUserService.list(Wrappers.<MaintainPlanContentUser>lambdaQuery().eq(MaintainPlanContentUser::getPlanId, planId));
				Map<Long, List<MaintainPlanContentUser>> listMap = planUserList.stream().collect(Collectors.groupingBy(MaintainPlanContentUser::getUserId));
				//改为新的执行人
				for (Long userId : asList) {
					List<MaintainPlanContentUser> maintainPlanContentUsers = listMap.get(userId);
					if (maintainPlanContentUsers == null || maintainPlanContentUsers.size() == 0) {
						//添加人员信息
						MaintainPlanContentUser maintainPlanContentUser = new MaintainPlanContentUser();
						maintainPlanContentUser.setUserId(Convert.toLong(userId));
						maintainPlanContentUser.setPlanId(planId);
						maintainPlanContentUser.setCreateFrom(createFrom);
						if (planContentSaveDto.getPlanArriveDate() != null) {
							maintainPlanContentUser.setPlanArriveDate(new Date(DateUtils.getNowDateEnd(planContentSaveDto.getPlanArriveDate())));
						}
						PlanUserSignDetailVo planUserSignDetailVo = new PlanUserSignDetailVo();
						planUserSignDetailVo.setUserName(userService.getById(Convert.toLong(userId)).getRealName());
						maintainPlanContentUser.setSignInfo(JSON.toJSONString(planUserSignDetailVo));
						maintainPlanContentUserService.save(maintainPlanContentUser);
					} else {
						MaintainPlanContentUser maintainPlanContentUser = maintainPlanContentUsers.get(0);
						maintainPlanContentUser.setCreateFrom(createFrom);
						maintainPlanContentUserService.updateById(maintainPlanContentUser);
						planUserList.remove(maintainPlanContentUser);
					}
				}
				//将原有的改为转出标签
				if (planUserList.size() > 0) {
					Integer createFrom2 = 2;//表示自己转出
					planUserList.forEach(o -> o.setCreateFrom(createFrom2));
					maintainPlanContentUserService.updateBatchById(planUserList);
				}
			}

			//发送消息
//			ElevatorSimpleInfoVO elevatorInfo = maintainPlanContentService.getElevatorSimpleInfo(planId);
//			MaintainMalfunctionWork maintainMalfunctionWork = this.getOne(Wrappers.<MaintainMalfunctionWork>lambdaQuery().eq(MaintainMalfunctionWork::getPlanId, planId).orderByAsc(MaintainMalfunctionWork::getId), false);
//			for (Long userId : asList) {
//				SimpleUserVO assignUserInfo = userService.getSimpleUserInfo(Convert.toLong(userId));
//				if (Func.isNotEmpty(assignUserInfo)) {
//					if (Func.isNotEmpty(assignUserInfo.getOpenid())) {
//						log.info("===========给维修发送模板消息,维修人:[{}]===========", assignUserInfo.getUserName());
//						// 跳转链接
//						String skipUrl = String.format("subpages/repair/repariDetail?elevatorId=%s&planId=%s", elevatorInfo.getElevatorId(), planId);
//						Map<String, String> templateDataMap = new HashMap<>(8);
//						templateDataMap.put("first", "您好，您有新的维修任务!");
//						templateDataMap.put("keyword1", maintainMalfunctionWork == null ? null : maintainMalfunctionWork.getName());
//						templateDataMap.put("keyword2", maintainMalfunctionWork == null ? null : maintainMalfunctionWork.getPhone());
//						templateDataMap.put("keyword3", DateUtil.format(new Date(), DatePattern.NORM_DATETIME_MINUTE_PATTERN));
//						templateDataMap.put("keyword4", maintainMalfunctionWork == null ? null : maintainMalfunctionWork.getMfDesc());
//						templateDataMap.put("remark", "请及时登录梯无忧小程序执行维修任务!");
//						templateDataMap.put("params", skipUrl);
//						weChatDialogueService.sendMsg(assignUserInfo.getOpenid(), TemplateMsgConstant.T_REPAIR_TASK_ID, templateDataMap);
//					}
//					log.info("===========给维修人发送手机短信,维修人:[{}], 手机号码:[{}]===========", assignUserInfo.getUserName(), assignUserInfo.getPhone());
//					Map<String, String> smsParam = new HashMap<>(2);
//					smsParam.put("auditStatus", getPlanStatusName(maintainPlanContent));
//					SmsUtil.sendMessage(MaintenanceSmsConstant.MAINTENANCE_PEOPLE, BladeConstant.ADMIN_TENANT_ID, smsParam, assignUserInfo.getPhone());
//
//					log.info("===========给维修人打电话,审批人:[{}], 手机号码:[{}]===========", assignUserInfo.getUserName(), assignUserInfo.getPhone());
//					Map<String, String> phoneMap = new HashMap<>(2);
//					phoneMap.put("place", elevatorInfo.getBuildingName() + elevatorInfo.getElevatorAddress());
//					VoiceTemplate voiceTemplate = new VoiceTemplate();
//					voiceTemplate.setTemplateCode(VoiceConstant.MAINTENANCE_ADD_USER);
//					voiceTemplate.setTemplateParam(phoneMap);
//					voiceTemplate.setPhoneNumber(assignUserInfo.getPhone());
//					asyncUtils.sendPhone(voiceTemplate);
//				}
//			}
		} else {
			throw new ServiceException("工单状态已变更请刷新页面");
		}


		//添加转派人员的预警信息-//计算维修到达时间
		planContentSaveDto.setPlanDate(DateUtil.format(new Date(), "yyyy-MM-dd"));
		List<PlanMaintainUserVO> maintainUserList = new ArrayList<>(16);
		for (Long userId : asList) {
			PlanMaintainUserVO planMaintainUserVO = new PlanMaintainUserVO();
			planMaintainUserVO.setMaintainUserId(userId);
			maintainUserList.add(planMaintainUserVO);
		}
		planContentSaveDto.setMaintainUserList(maintainUserList);
		this.sendYjMsg(planContentSaveDto, planId);
		return true;
	}

	@Override
	public List<MaintainMalfunctionWork> listByPlanId(Long planId) {
		return baseMapper.listByPlanId(planId);
	}

	@Override
	public void sendYjMsg(PlanContentSaveDto planContentSaveDto, Long planId) {

		//预计达到时间
		Date date2 = planContentSaveDto.getPlanArriveDate();

		//如果没有分配人员不处理
		if (planContentSaveDto.getMaintainUserList() == null || planContentSaveDto.getMaintainUserList().size() == 0) {
			return;
		}
		//如果不是立即分配不处理
		if (!planContentSaveDto.getPlanDate().equals(DateUtil.format(new Date(), "yyyy-MM-dd"))) {
			return;
		}
		//需求1:当人员指派10分钟后移动不超过500米-发送延迟
		MaintainWxmsgType detail = maintainWxmsgTypeService.detail(AuthUtil.getTenantId());
		if (detail == null || detail.getMoveTime() == null) {
			return;
		}
		long sendTime = DateUtil.date().getTime() + (detail.getMoveTime()) * 60000;
		JSONObject msg = new JSONObject();
		msg.put("contentType", MaintainPlanContentEnum.MAINTAIN_WX.getId());
		WxYjSendMsgVo wxYjSendMsgVo = new WxYjSendMsgVo();
		wxYjSendMsgVo.setType(1);
		wxYjSendMsgVo.setPlanArriveDate(date2);
		wxYjSendMsgVo.setPlanId(planId);
		List<PlanMaintainUserVO> maintainUserList = planContentSaveDto.getMaintainUserList();
		for (PlanMaintainUserVO planMaintainUserVO : maintainUserList) {
			Long maintainUserId = planMaintainUserVO.getMaintainUserId();
			UserTrajectory userTrajectory = userTrajectoryService.getOne(Wrappers.<UserTrajectory>lambdaQuery().between(UserTrajectory::getCreateTime, DateUtil.beginOfDay(new Date()), new Date()).eq(UserTrajectory::getUserId, maintainUserId).orderByDesc(UserTrajectory::getCreateTime).last("limit 1"));
			if (userTrajectory != null) {
				planMaintainUserVO.setLongitude(userTrajectory.getLongitude());
				planMaintainUserVO.setLatitude(userTrajectory.getLatitude());

				//计算每个用户的实际达到时间
				UserExt userExt = userExtService.getOne(Wrappers.<UserExt>lambdaQuery().eq(UserExt::getUserId, planMaintainUserVO.getMaintainUserId()));
				if (StrUtil.isNotEmpty(userExt.getVehicle())) {
					TenantConfig tenantConfig = tenantConfigService.getTenantConfig(AuthUtil.getTenantId());
					RescueScreenConfig rescueScreenConfig = tenantConfig.getRescueScreenConfig();
					Building building = buildingService.getById(planContentSaveDto.getBuildingId());
					MaintainPlanContentUser planContentUser = maintainPlanContentUserService.getOne(Wrappers.<MaintainPlanContentUser>lambdaQuery().eq(MaintainPlanContentUser::getUserId, planMaintainUserVO.getMaintainUserId()).eq(MaintainPlanContentUser::getPlanId, planId));
					//交通工具 1-自行车，2-摩托车，3-电动车，4-汽车，5-公交车，6-其它
					try {
						Integer distance = MapUtil.getDistance(MapUtil.getLongitude(userTrajectory.getLongitude()), MapUtil.getLongitude(userTrajectory.getLatitude()), MapUtil.getLongitude(building.getLongitude().toString()), MapUtil.getLongitude(building.getLatitude().toString()));
						BigDecimal multiply;
						if (userExt.getVehicle().equals("1")) {
							multiply = Convert.toBigDecimal(rescueScreenConfig.getBicycle()).multiply(Convert.toBigDecimal(1000));
						} else if (userExt.getVehicle().equals("2")) {
							multiply = Convert.toBigDecimal(rescueScreenConfig.getMotorcycle()).multiply(Convert.toBigDecimal(1000));
						} else if (userExt.getVehicle().equals("3")) {
							multiply = Convert.toBigDecimal(rescueScreenConfig.getElectricVehicle()).multiply(Convert.toBigDecimal(1000));
						} else if (userExt.getVehicle().equals("4")) {
							multiply = Convert.toBigDecimal(rescueScreenConfig.getCar()).multiply(Convert.toBigDecimal(1000));
						} else if (userExt.getVehicle().equals("5")) {
							multiply = Convert.toBigDecimal(rescueScreenConfig.getBus()).multiply(Convert.toBigDecimal(1000));
						} else {
							multiply = Convert.toBigDecimal(rescueScreenConfig.getOther()).multiply(Convert.toBigDecimal(1000));
						}
						BigDecimal divide = Convert.toBigDecimal(distance).divide(multiply.divide(Convert.toBigDecimal(60), 2, BigDecimal.ROUND_HALF_UP), 0, BigDecimal.ROUND_HALF_UP);
						planContentUser.setRealityPlanDate(new Date(DateUtils.getNowDateEnd(DateUtil.offsetMinute(new Date(), Convert.toInt(divide)))));
						planContentUser.setDistance(distance);
					} catch (Exception e) {

					}
					maintainPlanContentUserService.updateById(planContentUser);
				}
			}

		}
		List<PlanMaintainUserVO> userVOList = maintainUserList.stream().filter(o -> o.getLatitude() != null).collect(Collectors.toList());
		if (userVOList.size() > 0) {
			wxYjSendMsgVo.setMaintainUserList(userVOList);
			msg.put("wx_yj_msg", wxYjSendMsgVo);
			mqMessageService.sendWxWarnMsg(DateUtils.getNowDateEnd(new Date(sendTime)), JSONObject.toJSONString(msg));
		}

		//需求2：当人员预计到达时长剩余至项目要求到达时长的30%时，APP唤起手机语音提示“XX分后即将超时到达
		//预计达到时间
		if (planContentSaveDto.getPlanArriveDate() == null) {
			return;
		}
		Date date1 = new Date();
		long between = DateUtil.between(date1, date2, DateUnit.SECOND);

		//发送超时未达的延迟队列
		WxYjSendMsgVo wxYjSendMsgVo2 = new WxYjSendMsgVo();
		wxYjSendMsgVo2.setType(3);
		wxYjSendMsgVo2.setPlanId(planId);
		wxYjSendMsgVo2.setMaintainUserList(maintainUserList);
		wxYjSendMsgVo2.setPlanArriveDate(date2);
		msg.put("wx_yj_msg", wxYjSendMsgVo2);
		mqMessageService.sendWxWarnMsg(DateUtils.getNowDateEnd(date2), JSONObject.toJSONString(msg));
		//发送即将超时的延迟队列
		//计算百分之30
		BigDecimal divide = Convert.toBigDecimal((100 - detail.getAboutTimeoutRatio())).divide(Convert.toBigDecimal(100));
		between = Convert.toLong(Convert.toBigDecimal(between).multiply(divide));
		DateTime dateTime = DateUtil.offsetSecond(date1, Convert.toInt(between));
		WxYjSendMsgVo wxYjSendMsgVo3 = new WxYjSendMsgVo();
		wxYjSendMsgVo3.setType(2);
		wxYjSendMsgVo3.setPlanId(planId);
		wxYjSendMsgVo3.setPlanArriveDate(date2);
		wxYjSendMsgVo3.setMaintainUserList(maintainUserList);
		msg.put("wx_yj_msg", wxYjSendMsgVo3);
		mqMessageService.sendWxWarnMsg(DateUtils.getNowDateEnd(dateTime), JSONObject.toJSONString(msg));

		log.info("当人员指派10分钟后移动不超过500监听时间:" + DateUtil.format(new Date(sendTime), "yyyy-MM-dd HH:mm:ss"));
		log.info("超时未达的时间:" + DateUtil.format(new Date(date2.getTime()), "yyyy-MM-dd HH:mm:ss"));
		log.info("百分之30时间:" + DateUtil.format(new Date(dateTime.getTime()), "yyyy-MM-dd HH:mm:ss"));
	}

	@Override
	public List<WxUserPlanVo> userPlanListOfToday() {
		RedisTemplate<String, Object> redisTemplate = bladeRedis.getRedisTemplate();
		List<WxUserPlanVo> list = baseMapper.userPlanListOfToday(DateUtil.offsetDay(new Date(), -7), DateUtil.endOfDay(new Date()));
		redisTemplate.opsForValue().set(IMaintainMalfunctionWorkService.WX_USER_PLAN_KEY, JSON.toJSONString(list), 3600, TimeUnit.SECONDS);
		return list;
	}

	@Override
	public List<BiWxPlanDetailVo> getBiWxPlanDetailList(Date beginTime, Date endTime) {
		if (beginTime == null) {
			beginTime = DateUtil.offsetDay(new Date(), -365);
			endTime = new Date();
		}
		List<BiWxPlanDetailVo> biWxPlanDetailList = baseMapper.getBiWxPlanDetailList(beginTime, endTime);
		List<BiElevatorPrincaipalVo> biElevatorPrincipalLists = baseMapper.getBiElevatorPrincipalList();
		Map<Long, List<BiElevatorPrincaipalVo>> listMap1 = biElevatorPrincipalLists.stream().collect(Collectors.groupingBy(BiElevatorPrincaipalVo::getElevatorId));


		List<BiSignVo> biSignList = baseMapper.getBiSignList();
		Map<Long, List<BiSignVo>> listMap2 = biSignList.stream().collect(Collectors.groupingBy(BiSignVo::getPlanId));

		List<MaintainPlanContentUser> firstPlanUser = baseMapper.getFirstPlanUser();
		Map<Long, List<MaintainPlanContentUser>> listMap3 = firstPlanUser.stream().collect(Collectors.groupingBy(MaintainPlanContentUser::getPlanId));

		List<BiSignVo> biUserSignList = baseMapper.getBiUserSignList(beginTime, endTime);
		Map<Long, List<BiSignVo>> listMap4 = biUserSignList.stream().collect(Collectors.groupingBy(BiSignVo::getPlanId));
		for (BiWxPlanDetailVo biWxPlanDetailVo : biWxPlanDetailList) {
			//计算责任人和责任组
			List<BiElevatorPrincaipalVo> biElevatorPrincaipalVos = listMap1.get(biWxPlanDetailVo.getElevatorId());
			if (biElevatorPrincaipalVos != null && biElevatorPrincaipalVos.size() > 0) {
				BiElevatorPrincaipalVo biElevatorPrincaipalVo = biElevatorPrincaipalVos.get(0);
				biWxPlanDetailVo.setPrincipalUserNames(biElevatorPrincaipalVo.getUserNames());
				biWxPlanDetailVo.setPrincipalDeptNames(biElevatorPrincaipalVo.getDeptNames());
			}
			//计算签到的第一次时间和最后一次签退的时间
			List<BiSignVo> biSignVos = listMap2.get(biWxPlanDetailVo.getPlanId());
			if (biSignVos != null && biSignVos.size() > 0) {
				BiSignVo biSignVo = biSignVos.get(0);
				biWxPlanDetailVo.setFirstSignTime(biSignVo.getFirstSignTime());
				biWxPlanDetailVo.setEndSignOutTime(biSignVo.getEndSignOutTime());

				//计算作业耗时
				if (biSignVo.getFirstSignTime() != null && biSignVo.getEndSignOutTime() != null) {
					long betwee = DateUtil.between(biSignVo.getFirstSignTime(), biSignVo.getEndSignOutTime(), DateUnit.HOUR);
					biWxPlanDetailVo.setWorkHHour(Convert.toInt(betwee));
				}
			}

			List<MaintainPlanContentUser> maintainPlanContentUsers = listMap3.get(biWxPlanDetailVo.getPlanId());
			if (maintainPlanContentUsers != null && maintainPlanContentUsers.size() > 0) {
				//计算预计达到时间
				MaintainPlanContentUser maintainPlanContentUser = maintainPlanContentUsers.get(0);
				if (maintainPlanContentUser.getPlanArriveDate() != null) {
					long between = DateUtil.between(maintainPlanContentUser.getCreateTime(), maintainPlanContentUser.getPlanArriveDate(), DateUnit.MINUTE);
					biWxPlanDetailVo.setPlanArriveMinute(Convert.toStr(between));

					//计算实际达到耗时
					if (biWxPlanDetailVo.getFirstSignTime() != null) {
						long between2 = DateUtil.between(maintainPlanContentUser.getCreateTime(), biWxPlanDetailVo.getFirstSignTime(), DateUnit.MINUTE);
						biWxPlanDetailVo.setRealArriveHour(Convert.toBigDecimal(between2).divide(Convert.toBigDecimal(60), 2, BigDecimal.ROUND_HALF_UP));
					}
				}
			}

			//所有人员签到至签退总耗时+所有人员调度后至签到总耗时
			List<BiSignVo> biSignVos1 = listMap4.get(biWxPlanDetailVo.getPlanId());
			if (biSignVos1 != null && biSignVos1.size() > 0) {
				BigDecimal workWHour = Convert.toBigDecimal(biWxPlanDetailVo.getWorkWHour(), Convert.toBigDecimal(0));
				Integer allMin = 0;
				for (BiSignVo biSignVo : biSignVos1) {
					long between = DateUtil.between(biSignVo.getCreateTime(), biSignVo.getFirstSignTime(), DateUnit.MINUTE);
					allMin = allMin + Convert.toInt(between);
				}
				workWHour = workWHour.add(Convert.toBigDecimal(allMin).divide(Convert.toBigDecimal(60), 2, BigDecimal.ROUND_HALF_UP));
				biWxPlanDetailVo.setWorkAllHour(workWHour);
			}

			//计算面向客户完成时间
			if (biWxPlanDetailVo.getFinishPlanTime() != null && biWxPlanDetailVo.getPlanBeginTime() != null) {
				long between = DateUtil.between(biWxPlanDetailVo.getPlanBeginTime(), biWxPlanDetailVo.getFinishPlanTime(), DateUnit.HOUR);
				biWxPlanDetailVo.setClientWorkAllHour(Convert.toInt(between));
			}

		}
		return biWxPlanDetailList;
	}

	@Override
	public List<BiWxUserPlanVo> getBiWxUserPlanDetail(Date beginTime, Date endTime) {
		if (beginTime == null) {
			beginTime = DateUtil.offsetDay(new Date(), -365);
			endTime = new Date();
		}

		List<BiWxUserPlanVo> list = baseMapper.getBiWxUserPlanDetail(beginTime, endTime);

		List<BiElevatorPrincaipalVo> biElevatorPrincipalLists = baseMapper.getBiElevatorPrincipalList();
		Map<Long, List<BiElevatorPrincaipalVo>> listMap1 = biElevatorPrincipalLists.stream().collect(Collectors.groupingBy(BiElevatorPrincaipalVo::getElevatorId));

		List<BiWxPlanDetailVo> biWxPlanDetailList = baseMapper.getBiWxPlanDetailList(beginTime, endTime);
		Map<Long, List<BiWxPlanDetailVo>> listMap2 = biWxPlanDetailList.stream().collect(Collectors.groupingBy(BiWxPlanDetailVo::getPlanId));

		List<BiSignVo> biUserSignList = baseMapper.getBiUserSignList(beginTime, endTime);
		Map<Long, List<BiSignVo>> listMap3 = biUserSignList.stream().collect(Collectors.groupingBy(BiSignVo::getUserId));


		List<MaintainSign> signList = baseMapper.getWxGignList(beginTime, endTime);
		final Map<Long, List<MaintainSign>> listMap4 = signList.stream().collect(Collectors.groupingBy(MaintainSign::getUserId));
		for (BiWxUserPlanVo biWxUserPlanVo : list) {
			List<BiElevatorPrincaipalVo> biElevatorPrincaipalVos = listMap1.get(biWxUserPlanVo.getElevatorId());
			if (biElevatorPrincaipalVos != null && biElevatorPrincaipalVos.size() > 0) {
				BiElevatorPrincaipalVo biElevatorPrincaipalVo = biElevatorPrincaipalVos.get(0);
				biWxUserPlanVo.setPrincipalDeptNames(biElevatorPrincaipalVo.getDeptNames());
				biWxUserPlanVo.setPrincipalUserNames(biElevatorPrincaipalVo.getUserNames());
			}
			//处理执行人实际执行
			List<BiWxPlanDetailVo> biWxPlanDetailVos = listMap2.get(biWxUserPlanVo.getPlanId());
			if (biWxPlanDetailVos != null && biWxPlanDetailVos.size() > 0) {
				BiWxPlanDetailVo biWxPlanDetailVo = biWxPlanDetailVos.get(0);
				if (biWxPlanDetailVo.getStatus() == 4) {
					biWxUserPlanVo.setRealPlanUserNames(biWxPlanDetailVo.getRealPlanUserNames());
					biWxUserPlanVo.setPlanUserNames(biWxPlanDetailVo.getPlanUserNames());
				} else {
					biWxUserPlanVo.setPlanUserNames(biWxPlanDetailVo.getRealPlanUserNames());
				}
			}

			//第一次签到签退
			if (biWxUserPlanVo.getPlanId().equals(1871066333079998466L)) {
				System.out.println(123);
			}
			List<BiSignVo> biSignVos = listMap3.get(biWxUserPlanVo.getUserId());
			if (biSignVos != null && biSignVos.size() > 0) {
				List<BiSignVo> signVos = biSignVos.stream().filter(o -> o.getPlanId().equals(biWxUserPlanVo.getPlanId())).collect(Collectors.toList());
				if (signVos != null && signVos.size() > 0) {
					BiSignVo biSignVo = signVos.get(0);
					biWxUserPlanVo.setFirstSignTime(biSignVo.getFirstSignTime());
					biWxUserPlanVo.setEndSignOutTime(biSignVo.getEndSignOutTime());
				}
			}

			//计算预计达到时间
			if (biWxUserPlanVo.getPlanArriveDate() != null) {
				long between = DateUtil.between(biWxUserPlanVo.getAllocateTime(), biWxUserPlanVo.getPlanArriveDate(), DateUnit.MINUTE);
				biWxUserPlanVo.setPlanArriveMinute(Convert.toStr(between));

				//计算实际达到耗时
				if (biWxUserPlanVo.getFirstSignTime() != null) {
					long between2 = DateUtil.between(biWxUserPlanVo.getAllocateTime(), biWxUserPlanVo.getFirstSignTime(), DateUnit.MINUTE);
					if (between2 != 0) {
						biWxUserPlanVo.setRealArriveHour(Convert.toBigDecimal(between2).divide(Convert.toBigDecimal(60), 2, BigDecimal.ROUND_HALF_UP));
					}
				}
			}

			//计算作业总工时-所有签到签退的总和
			List<MaintainSign> maintainSigns = listMap4.get(biWxUserPlanVo.getUserId());
			if (maintainSigns != null && maintainSigns.size() > 0) {
				maintainSigns = maintainSigns.stream().filter(o -> o.getPlanId().equals(biWxUserPlanVo.getPlanId())).collect(Collectors.toList());
				Long minutes = 0L;
				for (MaintainSign maintainSign : maintainSigns) {
					if (maintainSign.getSignOutTime() != null && maintainSign.getSignTime() != null) {
						minutes = minutes + DateUtil.between(maintainSign.getSignTime(), maintainSign.getSignOutTime(), DateUnit.MINUTE);
					}
				}
				if (minutes > 0) {
					biWxUserPlanVo.setWorkWHour(Convert.toBigDecimal(minutes).divide(Convert.toBigDecimal(60), 2, BigDecimal.ROUND_HALF_UP));
				}
			}

			//完成总工时
			biWxUserPlanVo.setWorkAllHour(Convert.toBigDecimal(biWxUserPlanVo.getWorkWHour(), Convert.toBigDecimal(0)).add(Convert.toBigDecimal(biWxUserPlanVo.getRealArriveHour(), Convert.toBigDecimal(0))));
		}
		return list;
	}

	@Override
	public List<Map<String, Object>> getBiWxPlanDetailListV2() {
		return baseMapper.getBiWxPlanDetailListV2();
	}

	@Override
	public List<Map<String, Object>> galaxyRepairPlanCountJobV2() {
		return baseMapper.galaxyRepairPlanCountJobV2();
	}


	@Override
	public List<MalfunctionPartsTreeVO> selectMalPartsTree(String keyWord) {
		List<MalfunctionPartsTreeVO> list = new ArrayList<>(16);
		final List<MalfunctionPartsTreeVO> malfunctionPartsTreeVOS = baseMapper.selectMalPartsTree();
		if (StrUtil.isEmpty(keyWord)) {
			for (MalfunctionPartsTreeVO malfunctionPartsTreeVO : malfunctionPartsTreeVOS) {
				if (malfunctionPartsTreeVO.getChildren() == null) {
					continue;
				}
				for (MalfunctionPartsTreeVO malfunctionPartsTreeVO2 : malfunctionPartsTreeVO.getChildren()) {
					if (malfunctionPartsTreeVO2.getChildren() == null) {
						continue;
					}
					List<MalfunctionPartsTreeVO> threeChild = new ArrayList<>(16);
					for (MalfunctionPartsTreeVO malfunctionPartsTreeVO3 : malfunctionPartsTreeVO2.getChildren()) {
						if (malfunctionPartsTreeVO3.getName().contains("自定义")) {
							malfunctionPartsTreeVO3.setWeight(1);
						}
						threeChild.add(malfunctionPartsTreeVO3);
					}
					threeChild.sort(Comparator.comparing(MalfunctionPartsTreeVO::getWeight).reversed());
					malfunctionPartsTreeVO2.setChildren(threeChild);
				}
			}
			return malfunctionPartsTreeVOS;
		} else {
			List<MalfunctionPartsTreeVO> oneChild = new ArrayList<>(16);
			for (MalfunctionPartsTreeVO malfunctionPartsTreeVO : malfunctionPartsTreeVOS) {
				List<MalfunctionPartsTreeVO> children = malfunctionPartsTreeVO.getChildren();
				List<MalfunctionPartsTreeVO> towChild = new ArrayList<>(16);
				for (MalfunctionPartsTreeVO malfunctionPartsTreeVO1 : children) {
					List<MalfunctionPartsTreeVO> children1 = malfunctionPartsTreeVO1.getChildren();
					//第三级如果包括关键字就添加到第三级数组
					List<MalfunctionPartsTreeVO> threeChild = new ArrayList<>(16);
					for (MalfunctionPartsTreeVO malfunctionPartsTreeVO2 : children1) {
						if (malfunctionPartsTreeVO2.getName().contains(keyWord)) {
							threeChild.add(malfunctionPartsTreeVO2);
						}
					}

					//如果第三级数组大于0就设置到第二级的数组
					if (threeChild.size() > 0) {
						malfunctionPartsTreeVO1.setChildren(threeChild);
						towChild.add(malfunctionPartsTreeVO1);
					} else {
						malfunctionPartsTreeVO1.setChildren(null);
					}
				}
				//如果第二级数组大于0就设置到第一级的数组
				if (towChild.size() > 0) {
					malfunctionPartsTreeVO.setChildren(towChild);
					oneChild.add(malfunctionPartsTreeVO);
				}

			}
			return oneChild;
		}
	}


	@Override
	public List<Building> getBuildingListOfPlan(SugarSearchDTO searchDTO) {
		List<Long> deptIds = deptService.selectDeptAndAllChildIds(searchDTO.getDeptIds());
		List<ElevatorPrincipalDept> elevatorDepts = elevatorPrincipalDeptService.list(Wrappers.<ElevatorPrincipalDept>lambdaQuery().in(ElevatorPrincipalDept::getDeptId,deptIds));
		List<Long> elevatorIds = elevatorDepts.stream().map(ElevatorPrincipalDept::getElevatorId).distinct().collect(Collectors.toList());
		if(Func.isNotEmpty(elevatorIds)){
			return baseMapper.getBuildingListOfPlan(elevatorIds);
		}else {
			return new ArrayList<>();
		}
	}

	@Override
	public BuildingMapVo getBuildingMapInfo(SugarSearchDTO searchDTO) {
		BuildingMapVo buildingMapVo = new BuildingMapVo();

		List<Long> deptIds = deptService.selectDeptAndAllChildIds(searchDTO.getDeptIds());
		List<ElevatorPrincipalDept> elevatorDepts = elevatorPrincipalDeptService.list(Wrappers.<ElevatorPrincipalDept>lambdaQuery().in(ElevatorPrincipalDept::getDeptId,deptIds));
		List<Long> elevatorIds = elevatorDepts.stream().map(ElevatorPrincipalDept::getElevatorId).distinct().collect(Collectors.toList());

		Building building = buildingService.getById(searchDTO.getBuildingId());
		List<Dict> fault_problem = dictService.getList("building_type");
		Optional<Dict> faultProblem = fault_problem.stream().filter(o -> o.getDictKey().equals(building.getType())).findFirst();
		buildingMapVo.setBuildingName(building.getName());
		buildingMapVo.setTypeName(faultProblem.get().getDictValue());
		List<User> buildingMapInfo = baseMapper.getBuildingMapInfo(searchDTO.getBuildingId());
		buildingMapInfo = new ArrayList<>(buildingMapInfo.stream().filter(e -> {
				if (Func.isNotEmpty(e.getDeptId())) {
					for (Long deptId : deptIds) {
						if (e.getDeptId().contains(String.valueOf(deptId))) {
							return Boolean.TRUE;
						}
					}
				}
				return Boolean.FALSE;
			}).collect(Collectors.toMap(
				User::getId,
				p -> p,
				(existing, replacement) -> existing
			))
			.values());
		List<Elevator> planElevators = baseMapper.getPlanElevatorListOfBuildingId(searchDTO.getBuildingId());
		planElevators = planElevators.stream().filter(e -> elevatorIds.contains(e.getId())).collect(Collectors.toList());
		List<Elevator> elevators = elevatorService.list(Wrappers.<Elevator>lambdaQuery().eq(Elevator::getBuildingId, searchDTO.getBuildingId()));
		elevators = elevators.stream().filter(e -> elevatorIds.contains(e.getId())).collect(Collectors.toList());
		buildingMapVo.setUserList(buildingMapInfo);
		buildingMapVo.setElevatorCounts(elevators.size());
		buildingMapVo.setPlanElevatorCounts(planElevators.size());
		return buildingMapVo;
	}

	@Override
	public List<ElevatorMalTopVO> selectElevatorMalTopTen(SugarMalSearchDTO searchDTO) {

		List<Long> deptIds = deptService.selectDeptAndAllChildIds(searchDTO.getDeptIds());
		List<ElevatorPrincipalDept> elevatorDepts = elevatorPrincipalDeptService.list(Wrappers.<ElevatorPrincipalDept>lambdaQuery().in(ElevatorPrincipalDept::getDeptId,deptIds));
		List<Long> elevatorIds = elevatorDepts.stream().map(ElevatorPrincipalDept::getElevatorId).distinct().collect(Collectors.toList());
		List<ElevatorMalTopVO> result = new ArrayList<>();
		if(Func.isNotEmpty(elevatorIds)){
			result = baseMapper.selectElevatorMalTopTen(searchDTO);
			result = result.stream().filter(e -> elevatorIds.contains(e.getElevatorId())).collect(Collectors.toList());
		}
		if (ObjectUtil.isNotEmpty(result)) {
			result.sort(Comparator.comparing(ElevatorMalTopVO::getMalCount).reversed());
			if (result.size() > 10) {
				result = result.subList(0, 10);
			}
		}
		return result;
	}

	@Override
	public List<StatisticsTrendVO> selectMalProblemItem(SugarMalSearchDTO searchDTO) {
		Date startDate = searchDTO.getStartDate();
		Date endDate = searchDTO.getEndDate();
		if (searchDTO.getDataType().equals(2)) {
			startDate = DateUtil.beginOfWeek(startDate);
			endDate = DateUtil.endOfWeek(endDate);
		} else if (searchDTO.getDataType().equals(3)) {
			startDate = DateUtil.beginOfMonth(startDate);
			endDate = DateUtil.endOfMonth(endDate);
		}
		searchDTO.setStartDate(startDate);
		searchDTO.setEndDate(endDate);
		String[] labelArr = {"部件老化", "使用不当", "进水", "其他"};
		List<StatisticsTrendVO> result = this.initTrendEntirety(searchDTO, labelArr);
		List<MalListDTO> malListDTOS = baseMapper.selectMalList(searchDTO);
		malListDTOS = malListDTOS.stream().filter(e -> e.getPlanStatus().equals(TaskStatusEnum.WX_SIGN_FINISH.getStatus())).collect(Collectors.toList());
		if (ObjectUtil.isNotEmpty(malListDTOS)) {
			Map<String, List<MalListDTO>> dateGroup;
			if (searchDTO.getDataType().equals(1)) {
				dateGroup = malListDTOS.stream().collect(Collectors.groupingBy(e -> DateUtil.format(e.getPlanDate(), "yyyy/M/d")));
			} else if (searchDTO.getDataType().equals(2)) {
				dateGroup = malListDTOS.stream().collect(Collectors.groupingBy(t -> String.format("%s~%s", DateUtil.format(DateUtil.beginOfWeek(t.getPlanDate()), "yyyy/M/d"), DateUtil.format(DateUtil.endOfWeek(t.getPlanDate()), "yyyy/M/d"))));
			} else {
				dateGroup = malListDTOS.stream().collect(Collectors.groupingBy(t -> String.format("%s月", DateUtil.format(t.getPlanDate(), "yyyy年M"))));
			}
			result.forEach(e -> dateGroup.forEach((k, v) -> {
				long num;
				if (e.getType().equals(labelArr[0])) {
					num = v.stream().filter(j -> Func.toStrList(j.getFaultReasonItem()).contains("1")).count();
				} else if (e.getType().equals(labelArr[1])) {
					num = v.stream().filter(j -> Func.toStrList(j.getFaultReasonItem()).contains("2")).count();
				} else if (e.getType().equals(labelArr[2])) {
					num = v.stream().filter(j -> Func.toStrList(j.getFaultReasonItem()).contains("4")).count();
				} else {
					num = v.stream().filter(j -> !Func.toStrList(j.getFaultReasonItem()).contains("1")
						&& !Func.toStrList(j.getFaultReasonItem()).contains("2")
						&& !Func.toStrList(j.getFaultReasonItem()).contains("4")).count();
				}
				e.getTrendData().put(k, num);
			}));
		}
		return result;
	}

	@Override
	public List<StatisticsTrendVO> selectMalPlanTime(SugarMalSearchDTO searchDTO) {
		String[] labelArr = {"人员调度", "到达现场", "故障维修", "整体维修"};
		String[] itemArr = {"2h以上", "1.5h内", "1h以内", "30min内"};
		List<StatisticsTrendVO> result = this.initPlanTimeTrendEntirety(labelArr, itemArr);

		List<Long> deptIds = deptService.selectDeptAndAllChildIds(searchDTO.getDeptIds());
		List<ElevatorPrincipalDept> elevatorDepts = elevatorPrincipalDeptService.list(Wrappers.<ElevatorPrincipalDept>lambdaQuery().in(ElevatorPrincipalDept::getDeptId,deptIds));
		List<Long> elevatorIds = elevatorDepts.stream().map(ElevatorPrincipalDept::getElevatorId).distinct().collect(Collectors.toList());
		if(Func.isEmpty(elevatorIds)){
			return result;
		}
		List<MalListDTO> malListDTOS = baseMapper.selectMalList(searchDTO);
		if (Func.isNotEmpty(malListDTOS)) {
			malListDTOS = malListDTOS.stream().filter(e -> elevatorIds.contains(e.getElevatorId()) && e.getWorkOrderType().equals(WorkOrderTypeEnum.CLIENT.getId())).collect(Collectors.toList());
		}
		if (Func.isNotEmpty(malListDTOS)) {
			List<MalListDTO> finalMalListDTOS = malListDTOS;
			result.forEach(e -> {
				// 0~30
				long v1 = 0;
				// 30~60
				long v2 = 0;
				// 60~90
				long v3 = 0;
				// 大于120
				long v4 = 0;
				if (e.getType().equals(labelArr[0])) {
					v1 = finalMalListDTOS.stream().filter(j -> ObjectUtil.isNotEmpty(j.getAllocateDuration())
						&& j.getAllocateDuration() / 60000 <= 30 && j.getAllocateDuration() / 60000 >= 0).count();
					v2 = finalMalListDTOS.stream().filter(j -> ObjectUtil.isNotEmpty(j.getAllocateDuration())
						&& j.getAllocateDuration() / 60000 <= 60 && j.getAllocateDuration() / 60000 > 30).count();
					v3 = finalMalListDTOS.stream().filter(j -> ObjectUtil.isNotEmpty(j.getAllocateDuration())
						&& j.getAllocateDuration() / 60000 <= 90 && j.getAllocateDuration() / 60000 > 60).count();
					v4 = finalMalListDTOS.stream().filter(j -> ObjectUtil.isNotEmpty(j.getAllocateDuration())
						&& j.getAllocateDuration() / 60000 > 90).count();
				} else if (e.getType().equals(labelArr[1])) {
					v1 = finalMalListDTOS.stream().filter(j -> ObjectUtil.isNotEmpty(j.getArriveDuration())
						&& j.getArriveDuration() / 60000 <= 30 && j.getArriveDuration() / 60000 >= 0).count();
					v2 = finalMalListDTOS.stream().filter(j -> ObjectUtil.isNotEmpty(j.getArriveDuration())
						&& j.getArriveDuration() / 60000 <= 60 && j.getArriveDuration() / 60000 > 30).count();
					v3 = finalMalListDTOS.stream().filter(j -> ObjectUtil.isNotEmpty(j.getArriveDuration())
						&& j.getArriveDuration() / 60000 <= 90 && j.getArriveDuration() / 60000 > 60).count();
					v4 = finalMalListDTOS.stream().filter(j -> ObjectUtil.isNotEmpty(j.getArriveDuration())
						&& j.getArriveDuration() / 60000 > 90).count();
				} else if (e.getType().equals(labelArr[2])) {
					v1 = finalMalListDTOS.stream().filter(j -> ObjectUtil.isNotEmpty(j.getWorkMill())
						&& j.getWorkMill() / 60000 <= 30 && j.getWorkMill() / 60000 >= 0).count();
					v2 = finalMalListDTOS.stream().filter(j -> ObjectUtil.isNotEmpty(j.getWorkMill())
						&& j.getWorkMill() / 60000 <= 60 && j.getWorkMill() / 60000 > 30).count();
					v3 = finalMalListDTOS.stream().filter(j -> ObjectUtil.isNotEmpty(j.getWorkMill())
						&& j.getWorkMill() / 60000 <= 90 && j.getWorkMill() / 60000 > 60).count();
					v4 = finalMalListDTOS.stream().filter(j -> ObjectUtil.isNotEmpty(j.getWorkMill())
						&& j.getWorkMill() / 60000 > 90).count();
				} else if (e.getType().equals(labelArr[3])) {
					v1 = finalMalListDTOS.stream().filter(j -> ObjectUtil.isNotEmpty(j.getCreateTime()) && ObjectUtil.isNotEmpty(j.getPlanEndTime())
						&& (j.getPlanEndTime().getTime() - j.getCreateTime().getTime()) / 60000 <= 30 && (j.getPlanEndTime().getTime() - j.getCreateTime().getTime()) / 60000 >= 0).count();
					v2 = finalMalListDTOS.stream().filter(j -> ObjectUtil.isNotEmpty(j.getCreateTime()) && ObjectUtil.isNotEmpty(j.getPlanEndTime())
						&& (j.getPlanEndTime().getTime() - j.getCreateTime().getTime()) / 60000 <= 60 && (j.getPlanEndTime().getTime() - j.getCreateTime().getTime()) / 60000 > 30).count();
					v3 = finalMalListDTOS.stream().filter(j -> ObjectUtil.isNotEmpty(j.getCreateTime()) && ObjectUtil.isNotEmpty(j.getPlanEndTime())
						&& (j.getPlanEndTime().getTime() - j.getCreateTime().getTime()) / 60000 <= 90 && (j.getPlanEndTime().getTime() - j.getCreateTime().getTime()) / 60000 > 60).count();
					v4 = finalMalListDTOS.stream().filter(j -> ObjectUtil.isNotEmpty(j.getCreateTime()) && ObjectUtil.isNotEmpty(j.getPlanEndTime())
						&& (j.getPlanEndTime().getTime() - j.getCreateTime().getTime()) / 60000 > 90).count();
				}
				e.getTrendData().put(itemArr[0], v4);
				e.getTrendData().put(itemArr[1], v3);
				e.getTrendData().put(itemArr[2], v2);
				e.getTrendData().put(itemArr[3], v1);
			});
		}
		return result;
	}

	@Override
	public List<ElevatorMalTopVO> selectMalPlanTop(SugarMalSearchDTO searchDTO) {
		List<ElevatorMalTopVO> result = new ArrayList<>();
		List<Long> deptIds = deptService.selectDeptAndAllChildIds(searchDTO.getDeptIds());
		List<ElevatorPrincipalDept> elevatorDepts = elevatorPrincipalDeptService.list(Wrappers.<ElevatorPrincipalDept>lambdaQuery().in(ElevatorPrincipalDept::getDeptId,deptIds));
		List<Long> elevatorIds = elevatorDepts.stream().map(ElevatorPrincipalDept::getElevatorId).distinct().collect(Collectors.toList());
		if (searchDTO.getPlanGroupType().equals(1)) {
			List<Building> buildings = new ArrayList<>();
			List<MalListDTO> malListDTOS = new ArrayList<>();
			if(Func.isNotEmpty(elevatorIds)){
				List<Elevator> elevators = elevatorService.listByIds(elevatorIds);
				buildings = buildingService.listByIds(elevators.stream().map(Elevator::getBuildingId).distinct().collect(Collectors.toList()));
				malListDTOS = baseMapper.selectMalList(searchDTO);
				malListDTOS = malListDTOS.stream().filter(e -> elevatorIds.contains(e.getElevatorId())).collect(Collectors.toList());
			}
			if (Func.isNotEmpty(malListDTOS)) {
				malListDTOS = malListDTOS.stream().filter(e -> e.getWorkOrderType().equals(WorkOrderTypeEnum.CLIENT.getId())).collect(Collectors.toList());
			}
			if (ObjectUtil.isNotEmpty(buildings) && ObjectUtil.isNotEmpty(malListDTOS)) {
				Map<Long, List<MalListDTO>> buildingGroup = malListDTOS.stream().collect(Collectors.groupingBy(MalListDTO::getBuildingId));
				buildings = buildings.stream().filter(e -> buildingGroup.containsKey(e.getId())).collect(Collectors.toList());
				if (ObjectUtil.isNotEmpty(buildings)) {
					List<ElevatorMalTopVO> finalResult = new ArrayList<>();
					buildings.forEach(e -> {
						ElevatorMalTopVO topVO = new ElevatorMalTopVO();
						topVO.setBuildingName(e.getName());
						topVO.setMalCount(buildingGroup.get(e.getId()).stream().count());
						topVO.setPassMalCount(buildingGroup.get(e.getId()).stream().filter(j -> this.passWxPlanStatus(j.getPlanStatus())).count());
						long totalFinishPlan = buildingGroup.get(e.getId()).stream().filter(j -> j.getPlanStatus().equals(TaskStatusEnum.WX_SIGN_FINISH.getStatus())).count();
						if (totalFinishPlan > 0) {
							long totalFinishTime = buildingGroup.get(e.getId()).stream().filter(j -> j.getPlanStatus().equals(TaskStatusEnum.WX_SIGN_FINISH.getStatus()))
								.mapToLong(j -> j.getPlanEndTime().getTime() - j.getCreateTime().getTime()).sum();
							topVO.setPlanAveStr(DateUtils.millisecondToTime(totalFinishTime / totalFinishPlan));
						}
						finalResult.add(topVO);
					});
					result.addAll(finalResult);
					result.sort(Comparator.comparing(ElevatorMalTopVO::getMalCount).reversed());
					result = result.size() > 10 ? result.subList(0, 10) : result;
				}
			}
		}
		if (searchDTO.getPlanGroupType().equals(2)) {
			List<ElevatorSimpleInfoVO> elevatorSimpleInfoVOS = new ArrayList<>();
			List<MalListDTO> malListDTOS = new ArrayList<>();
			if(Func.isNotEmpty(elevatorIds)){
				elevatorSimpleInfoVOS = elevatorService.selectAllElevatorSimpleInfo();
				elevatorSimpleInfoVOS = elevatorSimpleInfoVOS.stream().filter(e -> elevatorIds.contains(e.getElevatorId())).collect(Collectors.toList());
				malListDTOS = baseMapper.selectMalList(searchDTO);
				malListDTOS = malListDTOS.stream().filter(e -> elevatorIds.contains(e.getElevatorId())).collect(Collectors.toList());
			}
			if (Func.isNotEmpty(malListDTOS)) {
				malListDTOS = malListDTOS.stream().filter(e -> e.getWorkOrderType().equals(WorkOrderTypeEnum.CLIENT.getId())).collect(Collectors.toList());
			}
			if (ObjectUtil.isNotEmpty(elevatorSimpleInfoVOS) && ObjectUtil.isNotEmpty(malListDTOS)) {
				Map<Long, List<MalListDTO>> elevatorGroup = malListDTOS.stream().collect(Collectors.groupingBy(MalListDTO::getElevatorId));
				elevatorSimpleInfoVOS = elevatorSimpleInfoVOS.stream().filter(e -> elevatorGroup.containsKey(e.getElevatorId())).collect(Collectors.toList());
				List<ElevatorMalTopVO> finalResult = new ArrayList<>();
				if (ObjectUtil.isNotEmpty(elevatorSimpleInfoVOS)) {
					elevatorSimpleInfoVOS.forEach(e -> {
						ElevatorMalTopVO topVO = new ElevatorMalTopVO();
						topVO.setBuildingName(e.getBuildingName());
						topVO.setElevatorAddress(e.getElevatorAddress());
						topVO.setMalCount(elevatorGroup.get(e.getElevatorId()).stream().count());
						topVO.setPassMalCount(elevatorGroup.get(e.getElevatorId()).stream().filter(j -> this.passWxPlanStatus(j.getPlanStatus())).count());
						long totalFinishPlan = elevatorGroup.get(e.getElevatorId()).stream().filter(j -> j.getPlanStatus().equals(TaskStatusEnum.WX_SIGN_FINISH.getStatus())).count();
						if (totalFinishPlan > 0) {
							long totalFinishTime = elevatorGroup.get(e.getElevatorId()).stream().filter(j -> j.getPlanStatus().equals(TaskStatusEnum.WX_SIGN_FINISH.getStatus()))
								.mapToLong(j -> j.getPlanEndTime().getTime() - j.getCreateTime().getTime()).sum();
							topVO.setPlanAveStr(DateUtils.millisecondToTime(totalFinishTime / totalFinishPlan));
						}
						finalResult.add(topVO);
					});
					result.addAll(finalResult);
					result.sort(Comparator.comparing(ElevatorMalTopVO::getMalCount).reversed());
					result = result.size() > 10 ? result.subList(0, 10) : result;
				}
			}
		}
		if (searchDTO.getPlanGroupType().equals(3)) {
			List<ElevatorDeptUserSimpleVO> eduSimpleVO = new ArrayList<>();
			List<MalListDTO> malListDTOS = new ArrayList<>();
			if(Func.isNotEmpty(elevatorIds)){
				eduSimpleVO = elevatorService.selectElevatorPrincipalDeptSimpleInfo();
				eduSimpleVO = eduSimpleVO.stream().filter(e -> elevatorIds.contains(e.getElevatorId())).collect(Collectors.toList());
				malListDTOS = baseMapper.selectElevatorDeptMalList(searchDTO);
				malListDTOS = malListDTOS.stream().filter(e -> elevatorIds.contains(e.getElevatorId())).collect(Collectors.toList());
			}
			if (Func.isNotEmpty(malListDTOS)) {
				malListDTOS = malListDTOS.stream().filter(e -> e.getWorkOrderType().equals(WorkOrderTypeEnum.CLIENT.getId())).collect(Collectors.toList());
			}
			if (ObjectUtil.isNotEmpty(eduSimpleVO) && ObjectUtil.isNotEmpty(malListDTOS)) {
				malListDTOS = malListDTOS.stream().collect(Collectors.collectingAndThen(
					Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(MalListDTO::getPlanId))), ArrayList::new
				));
				eduSimpleVO = eduSimpleVO.stream().collect(Collectors.collectingAndThen(
					Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(ElevatorDeptUserSimpleVO::getItemId))), ArrayList::new
				));
				Map<Long, List<MalListDTO>> deptGroup = malListDTOS.stream().collect(Collectors.groupingBy(MalListDTO::getDeptId));
				eduSimpleVO = eduSimpleVO.stream().filter(e -> deptGroup.containsKey(e.getItemId())).collect(Collectors.toList());
				if (ObjectUtil.isNotEmpty(eduSimpleVO)) {
					List<ElevatorMalTopVO> finalResult = new ArrayList<>();
					List<MalListDTO> finalMalListDTOS = malListDTOS;
					eduSimpleVO.forEach(e -> {
						ElevatorMalTopVO topVO = new ElevatorMalTopVO();
						topVO.setDeptName(e.getItemName());
						topVO.setMalCount(deptGroup.get(e.getItemId()).stream().count());
//						long totalFinishPlan = deptGroup.get(e.getItemId()).stream().filter(j -> j.getPlanStatus().equals(TaskStatusEnum.WX_SIGN_FINISH.getStatus())).count();
						if (e.getUserCount() > 0) {
							long totalFinishTime = deptGroup.get(e.getItemId()).stream().filter(j -> j.getPlanStatus().equals(TaskStatusEnum.WX_SIGN_FINISH.getStatus()))
								.mapToLong(MalListDTO::getWorkMill).sum();
							topVO.setPlanAveStr(DateUtils.millisecondToTime(totalFinishTime / e.getUserCount()));
							topVO.setPlanAve(BigDecimal.valueOf(topVO.getMalCount()).divide(BigDecimal.valueOf(e.getUserCount()), 1, RoundingMode.HALF_UP));
						}
						topVO.setPlanPer(BigDecimal.valueOf(deptGroup.get(e.getItemId()).size()).divide(BigDecimal.valueOf(finalMalListDTOS.size()), 3, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)).setScale(1, RoundingMode.HALF_UP));
						finalResult.add(topVO);
					});
					result.addAll(finalResult);
					result.sort(Comparator.comparing(ElevatorMalTopVO::getMalCount).reversed());
					result = result.size() > 10 ? result.subList(0, 10) : result;
				}
			}
		}
		if (searchDTO.getPlanGroupType().equals(4)) {
			List<MalListDTO> malListDTOS = new ArrayList<>();
			List<User> users = userService.list();
			List<Long> userIds = new ArrayList<>();
			deptIds.forEach(e -> {
				users.forEach(u -> {
					if(Func.isNotEmpty(u.getDeptId()) && u.getDeptId().contains(String.valueOf(e))){
						userIds.add(u.getId());
					}
				});
			});
			if(Func.isNotEmpty(userIds)){
				malListDTOS = baseMapper.selectPlanUserSimpleCount(searchDTO);
				malListDTOS = malListDTOS.stream().filter(e -> userIds.contains(e.getUserId())).collect(Collectors.toList());
			}
			if (Func.isNotEmpty(malListDTOS)) {
				malListDTOS = malListDTOS.stream().filter(e -> e.getWorkOrderType().equals(WorkOrderTypeEnum.CLIENT.getId())).collect(Collectors.toList());
			}
			if (ObjectUtil.isNotEmpty(malListDTOS)) {
				List<ElevatorDeptUserSimpleVO> eduSimpleVO = malListDTOS.stream().map(e -> {
					ElevatorDeptUserSimpleVO entity = new ElevatorDeptUserSimpleVO();
					entity.setItemName(e.getUserName());
					entity.setItemId(e.getUserId());
					return entity;
				}).collect(Collectors.toList());
				// 用户去重
				eduSimpleVO = eduSimpleVO.stream().collect(Collectors.collectingAndThen(
					Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(ElevatorDeptUserSimpleVO::getItemId))), ArrayList::new
				));
				Map<Long, List<MalListDTO>> userGroup = malListDTOS.stream().collect(Collectors.groupingBy(MalListDTO::getUserId));
				List<ElevatorMalTopVO> finalResult = new ArrayList<>();
				eduSimpleVO.forEach(e -> {
					ElevatorMalTopVO topVO = new ElevatorMalTopVO();
					topVO.setUserName(e.getItemName());
					topVO.setMalCount(userGroup.get(e.getItemId()).stream().map(MalListDTO::getPlanId).distinct().count());
					topVO.setFinishMalCount(userGroup.get(e.getItemId()).stream().filter(j -> j.getPlanStatus().equals(TaskStatusEnum.WX_SIGN_FINISH.getStatus())).map(MalListDTO::getPlanId).distinct().count());
					if (topVO.getFinishMalCount() > 0) {
						long totalUserWorkTime = userGroup.get(e.getItemId()).stream().filter(j -> j.getPlanStatus().equals(TaskStatusEnum.WX_SIGN_FINISH.getStatus())).mapToLong(MalListDTO::getUserWorkTime).sum();
						topVO.setPlanAveStr(DateUtils.millisecondToTime((totalUserWorkTime * 60000) / topVO.getFinishMalCount()));
					}
					finalResult.add(topVO);
				});
				result.addAll(finalResult);
				result.sort(Comparator.comparing(ElevatorMalTopVO::getMalCount).reversed());
				result = result.size() > 10 ? result.subList(0, 10) : result;
			}
		}
		return result;
	}

	@Override
	public Object initMal() {
		List<MaintainPlanContentExt> init = baseMapper.selectInitMal();
		List<MaintainPlanContentExt> result = new ArrayList<>();
		init.forEach(e -> {
			MaintainPlanContentExt planContentExt = new MaintainPlanContentExt();
			planContentExt.setId(e.getId());
			if (ObjectUtil.isNotEmpty(e.getArriveTime())) {
				planContentExt.setArriveTime(e.getArriveTime());
				planContentExt.setArriveDuration(e.getArriveTime().getTime() - e.getCreateTime().getTime());
			}
			if (ObjectUtil.isNotEmpty(e.getAllocateTime())) {
				planContentExt.setAllocateTime(e.getAllocateTime());
				planContentExt.setAllocateDuration((e.getAllocateTime().getTime() - e.getCreateTime().getTime()) < 0 ? 0 : (e.getAllocateTime().getTime() - e.getCreateTime().getTime()));
			}
			if (ObjectUtil.isNotEmpty(e.getWorkMinute())) {
				planContentExt.setWorkMill(BigDecimal.valueOf(e.getWorkMinute()).multiply(BigDecimal.valueOf(60000)).longValue());
			}
			result.add(planContentExt);
		});
		List<List<MaintainPlanContentExt>> resultList = ListUtil.partition(result, 100);
		resultList.forEach(e -> maintainPlanContentExtService.updateBatchById(e));
		return Boolean.TRUE;
	}

	@Override
	@Transactional
	public Object initFix() {
		List<MaintainPlanContentExt> list = maintainPlanContentExtService.list();
		list.forEach(f -> {
			if (!Func.isNull(f.getArriveDuration())) {
				if (f.getArriveDuration() > 1000 * 60 * 30) {
					f.setIsOvertime(1);
				}
			}
		});
		boolean b = maintainPlanContentExtService.updateBatchById(list);
		log.info("数据更新是否成功{}", b);
		return b;
	}


	/**
	 * 判断维修工单是否为已受理
	 *
	 * @param planStatus
	 * @return
	 */
	private Boolean passWxPlanStatus(Integer planStatus) {
		switch (planStatus) {
			case 2:
			case 3:
			case 4:
			case 7:
				return Boolean.TRUE;
			default:
				return Boolean.FALSE;
		}
	}

	private String getPlanStatusName(MaintainPlanContent maintainPlanContent) {
		return MaintainPlanContentWrapper.build().entityVO(maintainPlanContent).getStatusName();
	}

	/**
	 * @return
	 * @Author lsay
	 * @Description {
	 * 初始化耗时统计
	 * }
	 * @Date 11:21 2023/10/21
	 * @Param
	 **/
	private List<StatisticsTrendVO> initPlanTimeTrendEntirety(String[] labelArr, String[] itemArr) {
		List<StatisticsTrendVO> init = new ArrayList<>(labelArr.length);
		for (String label : labelArr) {
			StatisticsTrendVO trendVO = new StatisticsTrendVO();
			trendVO.setType(label);
			Map<String, Object> map = new LinkedHashMap<>(itemArr.length);
			for (String item : itemArr) {
				map.put(item, 0);
			}
			trendVO.setTrendData(map);
			init.add(trendVO);
		}
		return init;
	}

	/**
	 * 初始化救援趋势数据
	 *
	 * @param searchDTO
	 * @param initTypeArr
	 * @return
	 */
	private List<StatisticsTrendVO> initTrendEntirety(SugarMalSearchDTO searchDTO, String[] initTypeArr) {
		List<StatisticsTrendVO> initList = new ArrayList<>();
		for (String initType : initTypeArr) {
			StatisticsTrendVO init = new StatisticsTrendVO();
			init.setType(initType);
			Map<String, Object> trendData = new LinkedHashMap<>(32);
			if (searchDTO.getDataType().equals(1)) {
				// 日
				List<DateTime> rangeDate = DateUtil.rangeToList(searchDTO.getStartDate(), searchDTO.getEndDate(), DateField.DAY_OF_YEAR);
				rangeDate.forEach(date -> {
					trendData.put(DateUtil.format(date, "yyyy/M/d"), BigDecimal.ZERO);
				});
			} else if (searchDTO.getDataType().equals(2)) {
				// 周
				List<DateTime> rangeDate = DateUtil.rangeToList(searchDTO.getStartDate(), searchDTO.getEndDate(), DateField.DAY_OF_YEAR);
				rangeDate.forEach(date -> {
					String weekDate = String.format("%s~%s", DateUtil.format(DateUtil.beginOfWeek(date), "yyyy/M/d"), DateUtil.format(DateUtil.endOfWeek(date), "yyyy/M/d"));
					if (!trendData.containsKey(weekDate)) {
						trendData.put(weekDate, BigDecimal.ZERO);
					}
				});
			} else {
				// 月
				List<DateTime> rangeDate = DateUtil.rangeToList(searchDTO.getStartDate(), searchDTO.getEndDate(), DateField.MONTH);
				rangeDate.forEach(date -> {
					String monthDate = String.format("%s月", DateUtil.format(date, "yyyy年M"));
					trendData.put(monthDate, BigDecimal.ZERO);
				});
			}
			init.setTrendData(trendData);

			initList.add(init);
		}
		return initList;
	}
}


